#!/usr/bin/env python

"""
*****************************************************************
cmd_processing.py
This file is part of s60console project.

Released under GNU GPLv2.
See accompanying gpl-2.0.txt file
or visit http://www.gnu.org/licenses/gpl-2.0.txt

Author: Kashif Iftikhar (kashif [at] compulife.com.pk)

Description:
------------
Contains functions to process command line (s60console commands)

*****************************************************************
"""

import re
from utility_code import single_space

re_contact_number = re.compile("\+?\d+")


def parse_cmd_sendsms(cmd_str):
    """Parses the sendsms command
    Format is:
       sendsms contact message
    
       Contact may be: number | name
          number  = [+]X+ (where X is a digit, e.g, +923454564646 or 0435446654)
          name    = contact_name[[index]] (e.g, John, james[0] meaning james first phone number)
          message = string till the end of line
                       OR
                    multi-line string of format [[[ multi-line message ]]]
    
    """
    try:
        lines = cmd_str.split('\n')
        cmd_info = {'cmd': 'SENDSMS'}
        contact = single_space(lines[0]).split(' ')[0]
        cmd_info['contact'] = contact
        
        #check msg, whether it is a single line msg or multiple line msg.
        idx = lines[0].find(contact) + len(contact)
        if 1 == len(lines):
            msg = lines[0][idx:]
        else:
            msg = cmd_str[idx:]
            
            if msg.strip().startswith('[[['):
                i = msg.find('[[[') + 3
                msg = msg[i:]
            
            if msg.endswith(']]]'):
                msg = msg[:len(msg)-3]
        
        if '' == msg.strip():
            return "INVALID COMMAND"
        
        if msg.startswith("\n"):
            msg = msg[1:]
        
        if msg.startswith(' '):
            msg = msg[1:]
        
        cmd_info['message'] = msg.rstrip()
        
        
    except Exception:
        return "INVALID COMMAND"
    
    return cmd_info
    
def process_cmd_sendsms(cmd_info):
    """Given a command info dictionary object, processes it.
    Porcessing includes:
    - Translating contact names to contact numbers
    - Additional processing? [TODO]
    """
    
    #temporary way, will improve on it later on.
    from contacts import contacts
    
    if 'contact' in cmd_info:
        contact = cmd_info['contact']
        if not re_contact_number.match(contact):
            # not a number, so convert name to number.
            if contact in contacts:
                cmd_info['contact'] = contacts[contact]['mobile']
        
    return(cmd_info)
    
def parse_command(cmd_str):
    "Given a command string, parses it to its various components"
    
    cmd_info = {}
    print repr(cmd_str.split('\n'))
    cmd = single_space(cmd_str.split('\n')[0]).split(' ')[0].upper()
    print cmd_str
    print cmd
    
    if 'SENDSMS' == cmd:
        cmd_info = parse_cmd_sendsms(cmd_str[7:].strip())
        if cmd_info['message']:
            cmd_info['message'] = cmd_info['message'].strip()
    
    
    return cmd_info

def process_cmd(cmd_info):
    "Processes given command info according to the command"
    
    if 'cmd' in cmd_info:
        if 'SENDSMS' == cmd_info['cmd']:
            cmd_info = process_cmd_sendsms(cmd_info)
    
    return cmd_info

    

def _tests():
    "Test cases for the module"
    import sput
    
    T = sput.tester()

    

    def _test_parse_cmd_sendsms():
        "Unit tests for the parse_cmd_sendsms function"
        
        cmd = "+92343545454 This is just a simple msg"
        valid_r = {'message': ' This is just a simple msg', 'cmd': 'SENDSMS', 'contact': '+92343545454'}
        T.add_test("****** single line message command: %s" % cmd, parse_cmd_sendsms, valid_r, cmd)
        
        cmd = """+92343545454 [[[
        This is a message
        that spans
        multiple lines.
        ]]]"""
        valid_r = {'message': '        This is a message\n        that spans\n        multiple lines.', 'cmd': 'SENDSMS', 'contact': '+92343545454'}
        T.add_test("****** Multi-line message command: %s" % cmd, parse_cmd_sendsms, valid_r, cmd)
        
        cmd = """+92343545454 [[[
        This is a message
        that spans
        multiple lines.]]]"""
        valid_r = {'message': '        This is a message\n        that spans\n        multiple lines.', 'cmd': 'SENDSMS', 'contact': '+92343545454'}
        T.add_test("****** Multi-line message command 2: %s" % cmd, parse_cmd_sendsms, valid_r, cmd)
        
        cmd = ""
        valid_r = "INVALID COMMAND"
        T.add_test("****** Missing params command: %s" % cmd, parse_cmd_sendsms, valid_r, cmd)
        
        cmd = "atif"
        valid_r = "INVALID COMMAND"
        T.add_test("****** Missing params command: %s" % cmd, parse_cmd_sendsms, valid_r, cmd)
        
        
    
    def _test_parse_command():
        "Unit tests for the parse_command function"
        cmd = "sendsms +92343545454 This is just a simple msg"
        valid_r = {'message': 'This is just a simple msg', 'cmd': 'SENDSMS', 'contact': '+92343545454'}
        T.add_test("****** prase_command test. single line message command: %s" % cmd, parse_command, valid_r, cmd)
    
    def _test_process_cmd_sendsms():
        "Unit tests for process_cmd_sendsms"
        cmd_info = {'message': 'This is just a simple msg', 'cmd': 'SENDSMS', 'contact': 'Irum'}
        valid_r = {'message': 'This is just a simple msg', 'cmd': 'SENDSMS', 'contact': '03437158780'}
        T.add_test("****** process_cmd_sendsms test. Contact replace with number: %s" % repr(cmd_info), process_cmd_sendsms, valid_r, cmd_info)
        
        
    _test_parse_cmd_sendsms()
    _test_parse_command()
    _test_process_cmd_sendsms()
    
    T.run_all_tests()

if __name__ == '__main__':
    import sys
    
    if len(sys.argv)>1 and 'run_tests'==sys.argv[1]:
        _tests()
    
    